home *** CD-ROM | disk | FTP | other *** search
/ CU Amiga Super CD-ROM 23 / CU Amiga - Super CD-ROM 23 (June 1998).iso / CUCD / Graphics / STIMP_noise / source / include / STIMP / ppm.c < prev   
Encoding:
C/C++ Source or Header  |  1998-02-14  |  9.3 KB  |  408 lines

  1.  
  2. // PPM: declarations and routines
  3. // Version 2.15, 08.Feb.98
  4. // (c) 1997/98 by Stefan Diener
  5.  
  6. #ifndef STIMP_PPM_INC
  7. #define STIMP_PPM_INC
  8.  
  9. #include <STIMP/misc.c>
  10.  
  11. #ifndef NO_PSEUDO_PPM_MODE
  12. #ifndef NO_PSEUDO_PGM_MODE
  13. #define NO_PSEUDO_PGM_MODE
  14. #endif
  15. #include <STIMP/pbm.c>
  16. #include <STIMP/pgm.c>
  17. #endif
  18.  
  19. const PPM_PUFFER_SIZE=5001;
  20.  
  21. struct PPM_Info
  22. {
  23.   unsigned int height;
  24.   unsigned int width;
  25.   unsigned int maxval;
  26.   unsigned char *redData;
  27.   unsigned char *greenData;
  28.   unsigned char *blueData;
  29. };
  30.  
  31. #ifndef NO_PSEUDO_PPM_MODE
  32. int Copy_Picture(struct PPM_Info *info)
  33. {
  34.   int i, gesamt;
  35.   unsigned char *srcR, *srcG, *srcB;
  36.  
  37.   gesamt=info->width*info->height;
  38.  
  39.   // allocate memory for green picture data
  40.   info->greenData=NULL;
  41.   info->greenData=(unsigned char *) malloc(gesamt*sizeof(unsigned char));
  42.   if (info->greenData==NULL)
  43.   {
  44.     PrintMessage("No memory for green picture data left !");
  45.     free((void *) info->redData);
  46.     return 1;
  47.   }
  48.  
  49.   // allocate memory for blue picture data
  50.   info->blueData=NULL;
  51.   info->blueData=(unsigned char *) malloc(gesamt*sizeof(unsigned char));
  52.   if (info->blueData==NULL)
  53.   {
  54.     PrintMessage("No memory for blue picture data left !");
  55.     free((void *) info->redData);
  56.     free((void *) info->blueData);
  57.     return 1;
  58.   }
  59.  
  60.   // copy the red channel
  61.   srcR=info->redData;
  62.   srcG=info->greenData;
  63.   srcB=info->blueData;
  64.   for (i=0; i<gesamt; i++)
  65.   {
  66.      *srcG++=*srcR;
  67.      *srcB++=*srcR++;
  68.   }
  69.  
  70.   return 0;
  71. }
  72. #endif
  73.  
  74. int ReadPPMFile(char *name, struct PPM_Info *info)
  75. // read a PPM-file
  76. {
  77.   FILE *datei;
  78.   char tempo[5];
  79.   long int i, j, elemente, gesamt, anzahl;
  80.   unsigned char *srcR, *srcG, *srcB;
  81.   unsigned char *Puffer, *zeiger;
  82.  
  83.   if (strcmp("-",name)==0) datei=stdin;   // use stdin
  84.   else
  85.   {
  86.     // really open a file
  87.     datei=fopen(name,"rb");
  88.     if (datei==0)
  89.     {
  90.       PrintMessage("File %s not found !", name);
  91.       return 1;
  92.     }
  93.   }
  94.  
  95.   // set buffer size
  96.   setvbuf(datei,0,_IOFBF,1000);
  97.  
  98.   // check type
  99.   fgets(tempo, 4, datei);
  100.   correct(tempo);
  101.   if (strcmp(tempo,"P6")!=0)
  102.   {
  103.     if (strcmp("-",name)==0)
  104.     {
  105.       PrintMessage("Unknown file type: %s !",name);
  106.       return 1;
  107.     }
  108.     else
  109.     {
  110. #ifndef NO_PSEUDO_PPM_MODE
  111.       int error=0;
  112.       struct PBM_Info infoB;
  113.       struct PGM_Info infoG;
  114.  
  115.       fclose(datei);
  116.       switch (GetType(name))
  117.       {
  118.         case TYPE_PBM: error=ReadPBMFile(name, &infoB);
  119.                                   if (!error)
  120.                                   {
  121.                                     info->width=infoB.width;
  122.                                     info->height=infoB.height;
  123.                                     info->maxval=255;
  124.                                     info->redData=infoB.Data;
  125.                                     error=Copy_Picture(info);
  126.                                   }
  127.                                   return error;
  128.                                   break;
  129.  
  130.         case TYPE_PGM: error=ReadPGMFile(name, &infoG);
  131.                                   if (!error)
  132.                                   {
  133.                                     info->width=infoG.width;
  134.                                     info->height=infoG.height;
  135.                                     info->maxval=infoG.maxval;
  136.                                     info->redData=infoG.Data;
  137.                                     error=Copy_Picture(info);
  138.                                   }
  139.                                   return error;
  140.                                   break;
  141.  
  142.         default: return 1;
  143.                      break;
  144.       }
  145. #else
  146.       fclose(datei);
  147.       PrintMessage("Unknown file type %s !",name);
  148.       return 1;
  149. #endif
  150.     }
  151.   }
  152.  
  153.   // read dimensions and maxval
  154.   // skip comments !!!
  155.   ReadComment(datei);
  156.   fscanf(datei,"%i %i\n",&info->width,&info->height);
  157.   ReadComment(datei);
  158.   fscanf(datei,"%i\n",&info->maxval);
  159.  
  160.   // print it on the screen
  161.   PrintMessage("Reading %s (PPM, %ix%i)", name, info->width, info->height);
  162.   gesamt=info->width*info->height;
  163.  
  164.   // allocate memory for the read buffer
  165.   Puffer=NULL;
  166.   Puffer=(unsigned char *) malloc(PPM_PUFFER_SIZE*sizeof(unsigned char));
  167.   if (Puffer==NULL)
  168.   {
  169.     PrintMessage("No memory for the read buffer left !");
  170.     if (strcmp("-",name)!=0) fclose(datei);
  171.     return 1;
  172.   }
  173.  
  174.   // allocate memory for red picture data
  175.   info->redData=NULL;
  176.   info->redData=(unsigned char *) malloc(gesamt*sizeof(unsigned char));
  177.   if (info->redData==NULL)
  178.   {
  179.     PrintMessage("No memory for red picture data left !");
  180.     free((void *) Puffer);
  181.     if (strcmp("-",name)!=0) fclose(datei);
  182.     return 1;
  183.   }
  184.  
  185.   // allocate memory for green picture data
  186.   info->greenData=NULL;
  187.   info->greenData=(unsigned char *) malloc(gesamt*sizeof(unsigned char));
  188.   if (info->greenData==NULL)
  189.   {
  190.     PrintMessage("No memory for green picture data left !");
  191.     free((void *) Puffer);
  192.     free((void *) info->redData);
  193.     if (strcmp("-",name)!=0) fclose(datei);
  194.     return 1;
  195.   }
  196.  
  197.   // allocate memory for blue picture data
  198.   info->blueData=NULL;
  199.   info->blueData=(unsigned char *) malloc(gesamt*sizeof(unsigned char));
  200.   if (info->blueData==NULL)
  201.   {
  202.     PrintMessage("No memory for blue picture data left !");
  203.     if (strcmp("-",name)!=0) fclose(datei);
  204.     free((void *) Puffer);
  205.     free((void *) info->redData);
  206.     free((void *) info->greenData);
  207.     return 1;
  208.   }
  209.  
  210.   // need an empty picture
  211.   srcR=info->redData;
  212.   srcG=info->greenData;
  213.   srcB=info->blueData;
  214.   for (i=0; i<gesamt; i++)
  215.   {
  216.      *srcR++=0;
  217.      *srcG++=0;
  218.      *srcB++=0;
  219.   }
  220.  
  221.   // get pointers
  222.   srcR=info->redData;
  223.   srcG=info->greenData;
  224.   srcB=info->blueData;
  225.  
  226.   // read picture data
  227.   i=0;
  228.   elemente=PPM_PUFFER_SIZE/3;
  229.   while (i<gesamt)
  230.   {
  231.     anzahl=gesamt-i;
  232.     if (anzahl>elemente) anzahl=elemente;
  233.     j=fread((void *) Puffer, sizeof(unsigned char), anzahl*3, datei);
  234.     if (j!=anzahl*3)
  235.     {
  236.       i=gesamt;
  237.       PrintMessage("Error while reading the file !");
  238.     }
  239.     else
  240.     {
  241.       i+=anzahl;
  242.       zeiger=Puffer;
  243.       for (j=0; j<anzahl; j++)
  244.       {
  245.         *srcR++=*zeiger++;
  246.         *srcG++=*zeiger++;
  247.         *srcB++=*zeiger++;
  248.       }
  249.     }
  250.   }
  251.  
  252.   // free buffer memory
  253.   free((void *) Puffer);
  254.  
  255.   // close file
  256.   if (strcmp("-",name)!=0) fclose(datei);
  257.  
  258.   // ok
  259.   return 0;
  260. }
  261.  
  262. int WritePPMFile(char *name, struct PPM_Info *info)
  263. // write a PPM-file
  264. {
  265.   FILE *datei;
  266.   int i, j, anzahl, gesamt, elemente;
  267.   unsigned char *dstR, *dstG, *dstB;
  268.   unsigned char *Puffer, *zeiger;
  269.  
  270.   if (strcmp("-",name)==0) datei=stdout;   // use stdout
  271.   else
  272.   {
  273.     // really open a file
  274.     datei=fopen(name,"wb");
  275.     if (datei==0)
  276.     {
  277.       PrintMessage("Could not open destination file %s !", name);
  278.       return 1;
  279.     }
  280.   }
  281.  
  282.   PrintMessage("Writing %s (PPM, %ix%i)", name, info->width, info->height);
  283.  
  284.   // set buffer size
  285.   setvbuf(datei,0,_IOFBF,1000);
  286.  
  287.   // write file header
  288.   fprintf(datei,"P6\n");
  289.   fprintf(datei,"# written by: "OP_NAME" "VERSION" ("DATE"), author: "AUTHOR"\n");
  290.   fprintf(datei,"%i %i\n",info->width,info->height);
  291.   fprintf(datei,"%i\n",info->maxval);
  292.  
  293.   // allocate memory for write buffer
  294.   Puffer=NULL;
  295.   Puffer=(unsigned char *) malloc(PPM_PUFFER_SIZE*sizeof(unsigned char));
  296.   if (Puffer==NULL)
  297.   {
  298.     PrintMessage("No memory for write buffer left !");
  299.     if (strcmp("-",name)!=0) fclose(datei);
  300.     return 1;
  301.   }
  302.  
  303.   // write picture data
  304.   i=0;
  305.   elemente=PPM_PUFFER_SIZE/3;
  306.   gesamt=info->width*info->height;
  307.   dstR=info->redData;
  308.   dstG=info->greenData;
  309.   dstB=info->blueData;
  310.  
  311.   while (i<gesamt)
  312.   {
  313.     anzahl=gesamt-i;
  314.     if (anzahl>elemente) anzahl=elemente;
  315.     zeiger=Puffer;
  316.     for (j=0; j<anzahl; j++)
  317.     {
  318.       *zeiger++=*dstR++;
  319.       *zeiger++=*dstG++;
  320.       *zeiger++=*dstB++;
  321.     }
  322.  
  323.     j=fwrite((void *) Puffer, sizeof(unsigned char), anzahl*3, datei);
  324.     if (j!=anzahl*3)
  325.     {
  326.       i=gesamt;
  327.       PrintMessage("Error while writing the file !");
  328.     }
  329.     else i+=anzahl;
  330.   }
  331.  
  332.   // flush buffer and close file
  333.   fflush(datei);
  334.   if (strcmp("-",name)!=0) fclose(datei);
  335.  
  336.   // free buffer memory
  337.   free((void *) Puffer);
  338.  
  339.   // ok
  340.   return 0;
  341. }
  342.  
  343. int CreatePPMArray(int y, int x, struct PPM_Info *info)
  344. // allocate memory for a PPM-picture
  345. {
  346.   int i;
  347.   unsigned char *dstR, *dstG, *dstB;
  348.  
  349.   // save dimensions and maxval
  350.   info->width=x;
  351.   info->height=y;
  352.   info->maxval=255;
  353.  
  354.   // allocate memory for red picture data
  355.   info->redData=NULL;
  356.   info->redData=(unsigned char *) malloc(x*y*sizeof(unsigned char));
  357.   if (info->redData==NULL)
  358.   {
  359.     PrintMessage("No memory for red picture data left !");
  360.     return 1;
  361.   }
  362.  
  363.   // allocate memory for green picture data
  364.   info->greenData=NULL;
  365.   info->greenData=(unsigned char *) malloc(x*y*sizeof(unsigned char));
  366.   if (info->greenData==NULL)
  367.   {
  368.     PrintMessage("No memory for green picture data left !");
  369.     free((void *) info->redData);
  370.     return 1;
  371.   }
  372.  
  373.   // allocate memory for blue picture data
  374.   info->blueData=NULL;
  375.   info->blueData=(unsigned char *) malloc(x*y*sizeof(unsigned char));
  376.   if (info->blueData==NULL)
  377.   {
  378.     PrintMessage("No memory for blue picture data left !");
  379.     free((void *) info->redData);
  380.     free((void *) info->greenData);
  381.     return 1;
  382.   }
  383.  
  384.   // need an empty picture
  385.   dstR=info->redData;
  386.   dstG=info->greenData;
  387.   dstB=info->blueData;
  388.   for (i=0;i<info->width*info->height;i++)
  389.   {
  390.      *dstR++=0;
  391.      *dstG++=0;
  392.      *dstB++=0;
  393.   }
  394.  
  395.   // ok
  396.   return 0;
  397. }
  398.  
  399. void FreePPMArray(struct PPM_Info *info)
  400. // free the memory of a PPM-picture
  401. {
  402.   free((void *) info->redData);
  403.   free((void *) info->greenData);
  404.   free((void *) info->blueData);
  405. }
  406.  
  407. #endif
  408.